/*** 
 * @_______________#########_______________________ 
 * @______________############_____________________ 
 * @______________#############____________________ 
 * @_____________##__###########___________________ 
 * @____________###__######_#####__________________ 
 * @____________###_#######___####_________________ 
 * @___________###__##########_####________________ 
 * @__________####__###########_####_______________ 
 * @________#####___###########__#####_____________ 
 * @_______######___###_########___#####___________ 
 * @_______#####___###___########___######_________ 
 * @______######___###__###########___######_______ 
 * @_____######___####_##############__######______ 
 * @____#######__#####################_#######_____ 
 * @____#######__##############################____ 
 * @___#######__######_#################_#######___ 
 * @___#######__######_######_#########___######___ 
 * @___#######____##__######___######_____######___ 
 * @___#######________######____#####_____#####____ 
 * @____######________#####_____#####_____####_____ 
 * @_____#####________####______#####_____###______ 
 * @______#####______;###________###______#________ 
 * @________##_______####________####______________ 
 * @
 * @Author: ipk518 121206530@qq.com
 * @Date: 2025-02-11 11:49:46
 * @LastEditors: ipk518 121206530@qq.com
 * @LastEditTime: 2025-04-16 11:46:08
 * @FilePath: /etws-sxk2307/src/Uio/autoTbf.cpp
 * @Description: 
 * @************佛祖保佑************
 * @Copyright (c) 2025 by etws@quyujiang, All Rights Reserved. 
 */

#include "Server.h"
#include "math.h"
#include <ctime>
#include "getConfig.h"
#include "autoTbf.h"
#include "Gpio.h"
#include "queueShare.h"
#include "Uio.h"
#include "Common.h"
#include "autoCalibration.h"
using namespace std;

#define FREQPOINT_0 0
#define FREQPOINT_1 1

#define CHANNEL_NUM 32

#define TBF_CALCULATE_AMP    0
#define TBF_CALCULATE_PHASE  1

struct tr_mulit_freq_tbf tbf_mulitFreqStr[64];

tr_tbf_beam_t tbfCacheStr_H;
tr_tbf_beam_t tbfCacheStr_V;
tr_tbf_beam_t tbfSendStr;

static std::atomic<bool> m_refreshTbfSendH(false);//水平数据刷新标志位
static std::atomic<bool> m_refreshTbfSendV(false);//水平数据刷新标志位

autoTbf::autoTbf( )
{
    memset((uint8_t *)&tbfCacheStr_H,0,sizeof(tbfCacheStr_H));
    memset((uint8_t *)&tbfCacheStr_V,0,sizeof(tbfCacheStr_V));
    memset((uint8_t *)&tbfSendStr,0,sizeof(tbfSendStr));

    memset((uint8_t *)&tbf_mulitFreqStr,0,sizeof(tbf_mulitFreqStr));
    m_refreshTbfSendH = false;
    m_refreshTbfSendV = false;
    init();
}

autoTbf::~autoTbf()
{
    taskProcess = t_init;
    taskProcess1 = t_init;
    m_RunFlag = false;
    if (taskFd != nullptr)
    {
        taskFd->join();
        delete taskFd;
    }
    if (m_hSendCaliQueue != nullptr) {
        m_hSendCaliQueue->removeAll();
        delete m_hSendCaliQueue;
    }

    if (m_vSendCaliQueue != nullptr) {
        m_vSendCaliQueue->removeAll();
        delete m_vSendCaliQueue;
    }
}



void autoTbf::init()
{
    m_hSendCaliQueue = new queueShare();
    if (m_hSendCaliQueue == nullptr)
    {
       qlog_e("自动校准发射H极化数据队列初始化失败!");
        return;
    }  
    m_vSendCaliQueue = new queueShare();
    if (m_vSendCaliQueue == nullptr)
    {
        qlog_e("自动校准发射V极化数据队列初始化失败!");
        return;
    }  

    taskProcess = t_init;
    taskProcess1 = t_init;
    m_RunFlag = true;

    string str = Conf::currentConf()->mFilePath.uFreqReferencePath + string("/") + _TBF_REFERENCE_VALUE_ ;
    if(ReadFile(str.c_str(),(unsigned char *)&tbf_mulitFreqStr,sizeof(tbf_mulitFreqStr)) < 0){
        qlog_e("没有发现文件 %s,将使用程序内部默认值",str.c_str());
    }
    tbf_readCouplingParameters();//获取耦合系数
    taskFd = new std::thread(std::bind(&autoTbf::task, this));//定时任务
}

void autoTbf::test(char* m,int len)
{
    if(len < 2) {
        qlog_e("autoTbf,test参数错误");
        return;
    }
    int m_tesk = m[0];
    g_manualCnt = m[1];
    //循环次数
    g_manualAmpCnt = m[1];
    g_manualPhaCnt = g_manualAmpCnt;
    if(m_tesk == t_hCyclicTask || m_tesk == t_vCyclicTask) {
        setFreq(true);//使能发射赋型
    }
    taskProcess = (taskprocess)m_tesk;
    taskProcess1 = (taskprocess)m_tesk;
    
}

/*** 
 * @description: 需要去掉2个字节的频点信息
 * @param {int} m_flag
 * @return {*}
 */
void autoTbf::update(int m_flag,vector<uint8_t>& dataIn)
{
    if (taskProcess == t_getGps && taskProcess1 == t_wait) {
        return;
    }
    
    if (m_flag == uio_h_sendPolar) {
        std::unique_lock <std::mutex> lock(g_CaliMutex); 
        if ( m_hSendCaliQueue->dataIsValid() ) {
            m_hSendCaliQueue->removeAll();
        }
        m_hSendCaliQueue->recvfrom(dataIn.data(),dataIn.size());
        m_refreshTbfSendH = true;
    }
    if (m_flag == uio_v_sendPolar) {
        std::unique_lock <std::mutex> lock(g_CaliMutex); 
        if ( m_vSendCaliQueue->dataIsValid() ) {
            m_vSendCaliQueue->removeAll();
        }
        m_vSendCaliQueue->recvfrom(dataIn.data(),dataIn.size());
        m_refreshTbfSendV = true;
    }
}

/*** 
 * @description: 用于下发TR组件控制
 * @param {uioMode} to
 * @param {unsigned char} *dataOut
 * @param {unsigned int} dataLen
 * @return {*}
 */
void autoTbf::send(uioMode to,unsigned char *dataOut,unsigned int dataLen)
{
    int cmdTo = 0;
    static uint8_t data[66];
    if (to == uio_h_recvicePolar || to == uio_v_recvicePolar) {//接收校准
        cmdTo = 13;
        return;
    }
    else if (to == uio_h_sendPolar || to == uio_v_sendPolar) {//发射校准
        cmdTo = 13;
        taskBeamNum = (taskBeamNum < 63)?taskBeamNum:0;
        memcpy((uint8_t *)&tr_Cache.tbf[taskBeamNum],dataOut,dataLen);
    } else {
        qlog_e("发送TBF补平数据错误.");
        return;
    }
    int sendnum=0x01;
    struct cmdDataType cmdHeader;
    cmdHeader.DeviceType = t_controlCmd;
    cmdHeader.source_DevType = CurDeviceType;
    cmdHeader.source_DevNum = ComponentNO;
    cmdHeader.dst_DevType =  T_R_Sub_Unit_S;
    cmdHeader.dst_DevNum = 0;
    cmdHeader.cmdType = d_trCmd;
    cmdHeader.cmdChildType = cmdTo;
    cmdHeader.dataLen = 66;
    {
        data[0] = taskFreq;//频点
        data[1] = taskBeamNum;
        memcpy((uint8_t *)&data[2],dataOut,64);
    }   
    // qlog_hexdump("TBF补平Cmd",16,(uint8_t *)&cmdHeader,sizeof(cmdHeader));
    // qlog_hexdump("TBF补平Data",16,dataOut,dataLen);
    sendnum=0x01;
    Server::Instance().separate(s_dds,sendnum,&cmdHeader,data);
    sendnum=0x02;
    cmdHeader.dst_DevNum = 1;
    std::this_thread::sleep_for(std::chrono::milliseconds(500)); // 控制等待频率
    Server::Instance().separate(s_dds,sendnum,&cmdHeader,data);
}


/*** 
 * @description: 用于雷象差值上报
 * @param {uioMode} to
 * @return {*}
 */
void autoTbf::send(uioMode to)
{
    int sendnum=0xFFFF;
    struct cmdDataType cmdHeader;
    cmdHeader.DeviceType = t_controlCmd;
    cmdHeader.source_DevType = CurDeviceType;
    cmdHeader.source_DevNum = ComponentNO;
    cmdHeader.dst_DevType =  leixing_SERVER_Sub_Unit_S;
    cmdHeader.dst_DevNum = 0;

    if (to == uio_h_sendPolar) {//发射校准
        cmdHeader.cmdType = 0x0c;
        cmdHeader.cmdChildType = 1;
        cmdHeader.dataLen = sizeof(struct ap_update_t);
        Server::Instance().separate(s_web,sendnum,&cmdHeader,(uint8_t *)&webCache_H);
    } 
    if (to == uio_v_sendPolar) {
        cmdHeader.cmdType = 0x0c;
        cmdHeader.cmdChildType = 2;
        cmdHeader.dataLen = sizeof(struct ap_update_t);
        Server::Instance().separate(s_web,sendnum,&cmdHeader,(uint8_t *)&webCache_V);
    }
    if (to == uio_h_recvicePolar) {//接收校准
        cmdHeader.cmdType = 0x0c;
        cmdHeader.cmdChildType = 3;
        cmdHeader.dataLen = sizeof(struct ap_update_t);
        Server::Instance().separate(s_web,sendnum,&cmdHeader,(uint8_t *)&webCache_H);
    }
    if (to == uio_v_recvicePolar) {
        cmdHeader.cmdType = 0x0c;
        cmdHeader.cmdChildType = 4;
        cmdHeader.dataLen = sizeof(struct ap_update_t);
        Server::Instance().separate(s_web,sendnum,&cmdHeader,(uint8_t *)&webCache_V);
    }
    // qlog_hexdump("自动校准Cmd",16,(uint8_t *)&cmdHeader,sizeof(cmdHeader));
    // qlog_hexdump("自动校准Data",16,dataOut,dataLen);
}

bool autoTbf::getGps(unsigned long dueTime)
{
    if (Server::Instance().m_sxk.m_sysConfig.AutoCalibrationEN == 1) {
        time_t curTime;
        time(&curTime);//"1970到目前经过秒数:"机器内部计数

        int64_t handleTime = curTime - Server::Instance().m_sxk.m_sysConfig.AutoClockMark;
        if (handleTime >= (int64_t)dueTime) {
            qlog_i("触发间隔时间:%ds,时间间隔掩码:%d,当前时间:%d.",handleTime
            ,Server::Instance().m_sxk.m_sysConfig.AutoClockMark,curTime);
            qlog_i("触发自动校准");
            Server::Instance().m_sxk.m_sysConfig.AutoClockMark = curTime;//重置时间
            return true;//调试应该为TRUE
        } else {
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            return false;
        }
    }
    return false;
}


/*** 
 * @description: 自动校准
 * 1.PS通过GPS获取时间信息
 * 2.PS判断是否到校准时间节点
 * 3.AXI GPIO外设写1，然后写0
 * setGpioValue(PL_AUTO_ALIGN,1);
 * for(i=0;i<65536;i++){};
 * setGpioValue(PL_AUTO_ALIGN,0);
 * 4.等待时序发生器向PS发送校准完成中断
 * 5.获取发射通道校准IQ数据，并开始计算每个通道的幅度相位信息
 * 6.计算完成后将两个极化通道信息同上位机下发的通道幅相信息进行比较，并计算每个通道的幅相偏移值
 * 7.PS根据偏移值计算出修正值随后下发到TR对发射通道进行修正
 * 
 * @return {*}
 */
void autoTbf::task1()
{
    // static bool m_flag=true;
    // static uioMode m_status;
    // switch(taskProcess)
    // {
    //     case t_wait:
    //     break;
    //     case t_getGps:
    //         m_flag = getGps(Server::Instance().m_sxk.m_sysConfig.AutoCalibrationTime);
    //         (m_flag == true)?taskProcess = t_dueNode:taskProcess = t_getGps;
    //     break;
    //     case t_dueNode:
    //         m_flag = startOperate();
    //         if (m_flag == true) 
    //         {
    //             taskProcess = t_timingHandle;
    //             taskFreq = t_changeFreq1;
    //             taskFreq = readIntValue("params_config","freq_point",Server::Instance().m_configPath.c_str()) - 1;
    //             qlog_w("准备开始雷达自动校准,正在关闭发射赋性使能...");
    //         } else {
    //             taskProcess = t_getGps;
    //         }
    //     break;
    //     case t_timingHandle:
    //         {
    //             taskProcess = t_hSendValHandle;
    //             setGpioValue(Conf::currentConf()->mGpioConf.uPlAutoAlign,1);
    //             for(int i=0;i<65536;i++){};
    //             setGpioValue(Conf::currentConf()->mGpioConf.uPlAutoAlign,0);
    //             qlog_w("触发雷达自动校准...");
    //         }
    //     break;
    //     case t_hSendValHandle:
    //         qlog_w("自动校准运行中，请勿操作,H发射校准数据处理...");
    //         m_status = calcOffsetValue(uio_h_sendPolar,taskFreq,true);
    //         if (m_status == uio_h_sendPolar) {
    //             taskProcess = t_vSendValHandle;
    //         }
    //     break;
    //     case t_vSendValHandle:
    //         qlog_w("自动校准运行中，请勿操作,V发射校准数据处理...");
    //         m_status = calcOffsetValue(uio_v_sendPolar,taskFreq,true);
    //         if (m_status == uio_v_sendPolar) {
    //             taskProcess = t_end;
    //         }
            
    //     break;
    //     case t_end:
    //         // startCali(uio_finishCalib,taskFreq);
    //         {
    //             taskProcess = t_getGps;
    //             qlog_w("雷达自动校准,已完成!");
    //         }
    //     break;
    //     default:
    //         {
    //             taskProcess = t_getGps;
    //             qlog_w("雷达自动校准,复位!");
    //         }
    //     break;
    // }

}

/*  0：不加系数；
    1：加手动校准通道系数；
    2：加手动、自动校准通道系数；
    3：加耦合系数；
    4：加耦合系数、校准系数；*/
void autoTbf::task2()
{
    switch (taskProcess1) {
        case t_wait:
        break;
        case t_hCyclicTask:
            {
                string msg = "执行H极化发射校准,更新H极化TBF系数";
                qlog_w("%s.",msg.c_str());

                if (g_manualAmpCnt > 0) {
                    g_manualAmpCnt--;
                    startCali(uio_h_sendPolar);
                    std::this_thread::sleep_for(std::chrono::milliseconds(200));
                    calcOffsetValue2(uio_h_sendPolar,taskFreq,TBF_CALCULATE_AMP);
                    string msg1 = "可运行H极化发射校准手动幅度补偿的计数: " + to_string(g_manualAmpCnt);
                    qlog_w("%s.",msg1.c_str());
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                }
                else if ( g_manualAmpCnt == 0 && g_manualPhaCnt != 0 ) {
                    g_manualPhaCnt--;
                    startCali(uio_h_sendPolar);
                    std::this_thread::sleep_for(std::chrono::milliseconds(200));
                    calcOffsetValue2(uio_h_sendPolar,taskFreq,TBF_CALCULATE_PHASE);
                    string msg1 = "可运行H极化发射校准手动相位补偿的计数: " + to_string(g_manualPhaCnt);
                    qlog_w("%s.",msg1.c_str());
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                }

                if (g_manualAmpCnt == 0 && g_manualPhaCnt == 0) {
                    taskProcess1 = t_end;//结束
                }
                
            }
        break;
        case t_vCyclicTask:
            {
                string msg = "执行V极化发射校准,更新H极化TBF系数";
                qlog_w("%s.",msg.c_str());

                if (g_manualAmpCnt > 0) {
                    g_manualAmpCnt--;
                    startCali(uio_v_sendPolar);
                    std::this_thread::sleep_for(std::chrono::milliseconds(200));
                    calcOffsetValue2(uio_v_sendPolar,taskFreq,TBF_CALCULATE_AMP);
                    string msg1 = "可运行V极化发射校准手动幅度补偿的计数: " + to_string(g_manualAmpCnt);
                    qlog_w("%s.",msg1.c_str());
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                }
                else if ( g_manualAmpCnt == 0 && g_manualPhaCnt != 0 ) {
                    g_manualPhaCnt--;
                    startCali(uio_v_sendPolar);
                    std::this_thread::sleep_for(std::chrono::milliseconds(200));
                    calcOffsetValue2(uio_v_sendPolar,taskFreq,TBF_CALCULATE_PHASE);
                    string msg1 = "可运行V极化发射校准手动相位补偿的计数: " + to_string(g_manualPhaCnt);
                    qlog_w("%s.",msg1.c_str());
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
                }

                if(g_manualAmpCnt == 0 && g_manualPhaCnt == 0) {
                    taskProcess1 = t_end;////结束
                }

            }
        break;
        default:
            setFreq(false);//取消赋型使能
            taskProcess1 = t_wait;
            qlog_w("雷达TBF手动补平,复位!");
        break;
    }

}
/**
 * @description: 开启校准
 * @param {uioMode} st
 * @return {*}
 */
void autoTbf::startCali(uioMode st)
{
    Server::Instance().m_sxk.m_uio->m_pub->request(st);//开启校准
}

/** 
 * @description: 读取本地耦合系数
 * @param {int} freq
 * @return {*}
 */
int autoTbf::tbf_readCouplingParameters()
{
    std::string g_ucHFile,g_ucVFile;
    
    g_ucHFile = Conf::currentConf()->mFilePath.uFreqPointPath + std::string("/tbf_hPoint.dat");
    g_ucVFile = Conf::currentConf()->mFilePath.uFreqPointPath + std::string("/tbf_vPoint.dat");

    qlog_i("H极化TBF耦合系数路径:%s",g_ucHFile.c_str());
    qlog_i("V极化TBF耦合系数路径:%s",g_ucVFile.c_str());
    if(ReadFile(g_ucHFile.c_str(),(unsigned char *)hCoefficient,sizeof(hCoefficient)) < 0){
        qlog_e("没有发现H极化TBF文件路径 %s",g_ucHFile.c_str());
        return -1;
    }
    if(ReadFile(g_ucVFile.c_str(),(unsigned char *)vCoefficient,sizeof(vCoefficient)) < 0){
        qlog_e("没有发现V极化TBF文件路径 %s",g_ucVFile.c_str());
        return -1;
    }

    return 0;

}


/*** 
 * @description: 设置频点,使能发射赋型
 * @param {int} frequeue
 * @param {bool} enable
 * @return {*}
 */
bool autoTbf::setFreq(bool enable)
{
    bool ret = true;
    if(enable) {
        taskBeamNum = Server::Instance().m_gloabl.SpecifiedBeamNum;
        taskFreq = Server::Instance().m_gloabl.SpecifiedFreq;
        taskFreq = (taskFreq > 2)?0:taskFreq;
        taskBeamNum = (taskBeamNum > 63)?0:taskBeamNum;
        switch(taskFreq)
        {
            case t_changeFreq0:
                Server::Instance().m_sxk.changeBeamFreq(0,t_changeFreq0);
                Server::Instance().m_sxk.calibrationBeamMode(taskBeamNum,true);
                std::this_thread::sleep_for(std::chrono::milliseconds(200));
            break;
            case t_changeFreq1:
                Server::Instance().m_sxk.changeBeamFreq(0,t_changeFreq1);
                Server::Instance().m_sxk.calibrationBeamMode(taskBeamNum,true);
                std::this_thread::sleep_for(std::chrono::milliseconds(200));
            break;
            default:
                ret = false;
            break;
        }
    } else {
        Server::Instance().m_sxk.calibrationBeamMode(taskBeamNum,false);
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
    }
    
    return ret;
}



/*** 
 * @description: 获取当前校准数据
 * @param {uioMode} st
 * @param {unsigned char} *dataOut
 * @param {int} len
 * @return {*}
 */
void autoTbf::getCurrentCalibration(uioMode st,unsigned char *dataOut,int len)
{
    int timeout = 0;
    if ( st == uio_h_sendPolar ) {

        while ( !m_refreshTbfSendH.load() ) {
            timeout++;
            if(timeout > 50) {
                timeout = 0;
                qlog_e("等待H极化发射校准数据刷新超时.");
            }
            qlog_w("等待H极化发射校准数据刷新.");
            std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 控制等待频率
        }
        {//获取当前校准
            std::unique_lock<std::mutex> lk(g_CaliMutex);
            m_hSendCaliQueue->take();
            m_hSendCaliQueue->take();//2个字节的频率
            m_hSendCaliQueue->take((unsigned char *)dataOut,len);
            m_refreshTbfSendH = false;//取消刷新
        }
    } else if ( st == uio_v_sendPolar ) {
        while ( !m_refreshTbfSendV.load() ) {
            timeout++;
            if(timeout > 50) {
                timeout = 0;
                qlog_e("等待V极化发射校准数据刷新超时.");
            }
            qlog_w("等待V极化发射校准数据刷新.");
            std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 控制等待频率
        }
        {//获取当前校准
            std::unique_lock<std::mutex> lk(g_CaliMutex);
            m_vSendCaliQueue->take();
            m_vSendCaliQueue->take();//2个字节的频率
            m_vSendCaliQueue->take((unsigned char *)dataOut,len);
            m_refreshTbfSendV = false;//取消刷新
        }
    } else {
        qlog_e("获取当前TBF校准数据模式错误.");
    }
}




/*** 
 * @description: 减去耦合系数
 * @param {uioMode} st
 * @param {unsigned int} freq
 * @param {uint16_t*} calibrationData
 * @return {*}
 */
void autoTbf::subtractCouplingCoefficient(uioMode st, unsigned int freq, uint16_t* calibrationData) 
{
    int g_temp = 0;
    if (st == uio_h_sendPolar) {
        for(int i=0;i<CHANNEL_NUM;i++){
            calibrationData[i] = (uint16_t)((calibrationData[i] - (hCoefficient[freq][i]*100)));
            g_temp = (calibrationData[i + CHANNEL_NUM]-(hCoefficient[freq][i + CHANNEL_NUM]*10)); //TODO:2024-12-12取模
            calibrationData[i+CHANNEL_NUM] = getModulo(g_temp,3600);
        }
    } else if (st == uio_v_sendPolar) {
        for(int i=0;i<CHANNEL_NUM;i++){
            calibrationData[i] = (uint16_t)((calibrationData[i] - (vCoefficient[freq][i]*100)));
            g_temp = (calibrationData[i + CHANNEL_NUM]-(vCoefficient[freq][i + CHANNEL_NUM]*10)); //TODO:2024-12-12取模
            calibrationData[i+CHANNEL_NUM] = getModulo(g_temp,3600);
        }
    }
}

/*** 
 * @description: 更新TBF幅度值，并下发到TR
 * @param {uioMode} st
 * @param {unsigned int} freq
 * @param {uint16_t*} srcData
 * @param {uint16_t} *standAmpData
 * @return {*}
 */
void autoTbf::updateAmplitudeOffset(uioMode st, unsigned int freq,const uint16_t* srcData,const uint16_t *standAmpData) 
{  
    int i=0,g_iTemp0=0;
    float g_fTemp0=0;
    int m_tmp[CHANNEL_NUM];

    {//计算偏移量
        
        memset(m_tmp,0,sizeof(m_tmp));
        memset((uint8_t *)&tbfSendStr,0,sizeof(tbfSendStr));
        // ddsSendStr.freq = freq; //记录频点
        webCache_H.freq = freq;
        for (i=0; i < CHANNEL_NUM; i++) {
            g_iTemp0 = srcData[i] - standAmpData[i];//记录下校准值的差值,用于上报雷象日志
            if (g_iTemp0 >= 50) { //通道值实际比标准值小，那么不需要计算修正衰减值
                
                g_fTemp0 = static_cast<float>(((g_iTemp0)/0.5/2)/100);//换算比例0.5dbm，除2分级调节
                g_iTemp0 = ceil(g_fTemp0);
                tbfSendStr.tbf_atten[i] = g_iTemp0;
            } else {
                tbfSendStr.tbf_atten[i] = 0;
            }
        }

        
    }
    if (st == uio_h_sendPolar) { //保存一组缓存幅相值

        for(i=0; i<CHANNEL_NUM; i++) {

            tbfSendStr.tbf_atten[i] += tbfCacheStr_H.tbf_atten[i];

            if (tbfSendStr.tbf_atten[i] > m_tmp[i]) {
                tbfSendStr.tbf_atten[i] -= m_tmp[i];
            }
            if(tbfSendStr.tbf_atten[i] > 62) {
                tbfSendStr.tbf_atten[i] = 63;
            }
#if _LOG_UIO_
            qlog_n("H极化TBF幅度补平通道%d,幅度标准值:%d,校准值:%d,幅度下发值:%d.",i,
            standAmpData[i],srcData[i],tbfSendStr.tbf_atten[i]);
#endif
        }
        memcpy(tbfCacheStr_H.tbf_atten,tbfSendStr.tbf_atten,sizeof(tbfCacheStr_H.tbf_atten));
        send(uio_h_sendPolar,(unsigned char *)&tbfCacheStr_H,sizeof(ddsCacheStr_H));
    } else if(st == uio_v_sendPolar) {

        for(i=0; i<CHANNEL_NUM; i++) {

            tbfSendStr.tbf_atten[i] += tbfCacheStr_V.tbf_atten[i];

            if (tbfSendStr.tbf_atten[i] > m_tmp[i]) {
                tbfSendStr.tbf_atten[i] -= m_tmp[i];
            }
            if(tbfSendStr.tbf_atten[i] > 62) {
                tbfSendStr.tbf_atten[i] = 63;
            }
#if _LOG_UIO_
            qlog_n("V极化TBF幅度补平通道%d,幅度标准值:%d,校准值:%d,幅度下发值:%d.",i,
            standAmpData[i],srcData[i],tbfCacheStr_V.tbf_atten[i]);
#endif
        }
        memcpy(&tbfCacheStr_V.tbf_atten,tbfSendStr.tbf_atten,sizeof(tbfCacheStr_V.tbf_atten));
        send(uio_v_sendPolar,(unsigned char *)&tbfCacheStr_V,sizeof(tbfCacheStr_V));
    } else {
        qlog_e("幅度偏移值计算,校准模式错误.");
    }
    
}  


#define ANGLE_RATE  56.25

/*** 
 * @description: 更新TBF相位值，并下发到TR
 * @param {uioMode} st
 * @param {unsigned int} freq
 * @param {uint16_t*} srcData
 * @param {uint16_t} *standPhaseData
 * @return {*}
 */
void autoTbf::updatePhaseOffset(uioMode st, unsigned int freq,const uint16_t* srcData,const uint16_t *standPhaseData) 
{  
    int i=0,g_iTemp0=0;
    float g_fTemp0=0;
    int m_tmp[CHANNEL_NUM];

    {//计算偏移量
        memset(m_tmp,0,sizeof(m_tmp));
        memset((uint8_t *)&tbfSendStr,0,sizeof(tbfSendStr));

        // ddsSendStr.freq = freq; //记录频点
        webCache_H.freq = freq;
        for (i=0; i < CHANNEL_NUM; i++) {

            g_iTemp0 = srcData[i+CHANNEL_NUM] - standPhaseData[i];
            webCache_H.ddsPhase[i] = g_iTemp0;//记录下相位校准值的差值,用于上报雷象日志
            if(!is_within_tolerance(srcData[i+CHANNEL_NUM],standPhaseData[i])) { //不在50以内就处理
            
                if(g_iTemp0 > 0) {
                    g_fTemp0 = (float)(getModulo(g_iTemp0,3600) / getIntRandom(2,3));  //大于0处理方式

                } else { //小于0的处理方式
                    g_fTemp0 =  (float)(3600 - (abs(g_iTemp0) / getIntRandom(2,3))); //取负值 
  
                }
                tbfSendStr.tbf_ps[i] = static_cast<int>(((g_fTemp0/ANGLE_RATE) + 0.5));//四舍五入

            } else {
                tbfSendStr.tbf_ps[i] = 0;
            }
            
        }
    }
    if(st == uio_h_sendPolar)
    { //保存一组缓存幅相值
        int m = 0;
        for(i=0; i<CHANNEL_NUM; i++) {
            m = tbfSendStr.tbf_ps[i];

            tbfSendStr.tbf_ps[i] += tbfCacheStr_H.tbf_ps[i];
            tbfSendStr.tbf_ps[i] = getModulo(tbfSendStr.tbf_ps[i],64);
#if _LOG_UIO_
            qlog_n("H极化TBF相位补平通道%d,相位标准值:%d,相位值:%d,修正值：%d,本次下发值:%d.",i,standPhaseData[i],srcData[i+CHANNEL_NUM],m,tbfSendStr.tbf_ps[i]);
#endif
        }
        memcpy(tbfCacheStr_H.tbf_ps,tbfSendStr.tbf_ps,sizeof(tbfCacheStr_H.tbf_ps));
        send(uio_h_sendPolar,(unsigned char *)&tbfCacheStr_H,sizeof(tbfCacheStr_H));
    } else if(st == uio_v_sendPolar) {

        int m = 0;
        for(i=0; i<CHANNEL_NUM; i++) {
            m = tbfSendStr.tbf_ps[i];

            tbfSendStr.tbf_ps[i] += tbfCacheStr_V.tbf_ps[i];
            tbfSendStr.tbf_ps[i] = getModulo(tbfSendStr.tbf_ps[i],64);
#if _LOG_UIO_
            qlog_n("V极化TBF相位补平通道%d,相位标准值:%d,相位值:%d,修正值：%d,本次下发值:%d.",i,standPhaseData[i],srcData[i+CHANNEL_NUM],m,tbfSendStr.tbf_ps[i]);
#endif
        }
        memcpy(tbfCacheStr_V.tbf_ps,tbfSendStr.tbf_ps,sizeof(tbfCacheStr_V.tbf_ps));
        send(uio_v_sendPolar,(unsigned char *)&tbfCacheStr_V,sizeof(tbfCacheStr_V));
    } else {
        qlog_e("相位偏移值计算,校准模式错误.");
    }
    

}  

/*** 
 * @description: 计算当前幅度补偿值第二版
 * 幅度修正值计算：将获取出来的IQ换算成幅相值后减去通道耦合系数，再减去下发的多评点幅度基准值。最后得到的值除以0.5dbm取整。
 * 相位修正值计算：将获取出来的IQ换算成相位值后将去通道耦合系数，判断是否大于360，如果是则用360减去这个相位值后再减去相位基准值，最后除以5.625取整。
 *                                                                           如果小于360，则将相位值减去相位基准值，最后除以5.625取整。
 * @param {uioMode} st
 * @param {unsigned int} freq
 * @param {bool} update
 * @param {int} apMode(选幅度还是相位补偿)
 * @return {*}
 */
uioMode autoTbf::calcOffsetValue2(uioMode st,unsigned int freq, int apMode)
{
    static uint16_t m_dataTmp[32];
    //1、获取校准值，需要先触发PL校准
    getCurrentCalibration(st,(unsigned char *)g_usSendData[0],sizeof(g_usSendData[0]));
    //2、将数据减耦合系数
    subtractCouplingCoefficient(st,freq,g_usSendData[0]);
    if(apMode == TBF_CALCULATE_AMP) {
        //3、计算并下发幅度偏移值
        memcpy(m_dataTmp,tbf_mulitFreqStr[taskBeamNum].SendAmp[freq],sizeof(m_dataTmp));
        updateAmplitudeOffset(st,freq,g_usSendData[0],m_dataTmp); 
    } 
    
    if (apMode == TBF_CALCULATE_PHASE) {
        //3、计算并下发相位偏移值
        memcpy(m_dataTmp,tbf_mulitFreqStr[taskBeamNum].SendPhase[freq],sizeof(m_dataTmp));
        updatePhaseOffset(st,freq,g_usSendData[0],m_dataTmp); 
    }
    return st;
}


/*** 
 * @description: 清除幅度相位值
 * @return {*}
 */
void autoTbf::clearTBF()
{
    qlog_w("雷达自动校准,TR组件发幅相缓存值清0");
    memset((uint8_t *)&tbfSendStr,0,sizeof(tbfSendStr));
    send(uio_h_sendPolar,(unsigned char *)&tbfSendStr,sizeof(tbfSendStr));//TODO:测试流程不下发
    std::this_thread::sleep_for(std::chrono::milliseconds(20));
    send(uio_v_sendPolar,(unsigned char *)&tbfSendStr,sizeof(tbfSendStr));//TODO:测试流程不下发
    std::this_thread::sleep_for(std::chrono::milliseconds(20));
}

/**
 * @description: 处理雷达状态
 * @return {*}
 */
bool autoTbf::startOperate()
{
    m_frequeuce = readIntValue("paramsConfig","freqPoint",Server::Instance().m_configPath.c_str());//并记录当前校准参数频点
    return (Server::Instance().m_sxk.m_controlReg.m_timingStatus == 0x01);//如果雷达正在运行，那么可以开始校准
}

/*** 
 * @description: 设置雷达运行状态
 * @return {*}
 */
void autoTbf::setOperate(bool ret)
{
    if(ret) {
        Server::Instance().m_sxk.m_controlReg.m_timingStatus = 0x01;
    } else {
        Server::Instance().m_sxk.m_controlReg.m_timingStatus = 0x06;
    }
    Server::Instance().m_event.triggerEvent(WRITE_CONTROL_REG);//启动写入控制寄存器
    std::this_thread::sleep_for(std::chrono::milliseconds(20));
}


/**
 * @description: 定时任务
 * @param {SXK_Unit} *argc
 * @return {*}
 */
void autoTbf::task(autoTbf *argc)
{    
    pthread_setname_np(pthread_self(),"tbf_task");
    while(argc->m_RunFlag)
    {    
        if (sysRunStatus != SYS_RUN) {
            qlog_d("TBF自动校准线程暂停运行...");
            std::this_thread::sleep_for(std::chrono::milliseconds(600));
            continue;
        }
        argc->task1();
        argc->task2();
        std::this_thread::sleep_for(std::chrono::milliseconds(20));
    }

}